/*
 * Socket.cpp
 *
 *  Created on: 23/05/2012
 *      Author: sebastian
 */

#include "common_Socket.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include "common.h"

Socket::Socket(const char* ports) {
	puerto = Auxiliar::stoi(ports);
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
}

Socket::Socket(const char* ports, int sock_fd) {
	puerto = Auxiliar::stoi(ports);
	sockfd = sock_fd;
}

Socket::Socket(int port, int fd) {
	puerto = port;
	sockfd = fd;
}

Socket::~Socket() {
}

int Socket::conectar(std::string dir) {
	struct hostent *he;
	he = gethostbyname(dir.c_str());
	struct sockaddr_in their_addr;
	their_addr.sin_family = AF_INET;
	their_addr.sin_port = htons(puerto);
	their_addr.sin_addr = *((struct in_addr *)he->h_addr);
	memset(&(their_addr.sin_zero), 8, sizeof(int));
	return connect(sockfd, (struct sockaddr *)&their_addr,
	sizeof(struct sockaddr));
}


int Socket::recibir(char* buf, unsigned int size) {
	int i = recv(sockfd, buf, size, 0);
	return i;
}

int Socket::recibir(int clientfd, char* buf, unsigned int size) {
	int i = recv(clientfd, buf, size, 0);
	return i;
}

void Socket::escuchar() {
	listen(sockfd, MAX_CON);
}

void Socket::enlazar() {
	struct sockaddr_in addr;
	memset((char *)&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(puerto);
	addr.sin_addr.s_addr = INADDR_ANY;
	bind(sockfd, (struct sockaddr *)&addr, (socklen_t)sizeof(struct sockaddr));
}

int Socket::enviar(int clientfd, std::string data) {
	int n = send(clientfd, data.c_str(), data.size(), 0);
	if(n == -1)
		return -1;
	while((unsigned int)n < data.size()) {
		std::string saux = data.substr(n);
		n += send(clientfd, saux.c_str(), n - data.size(), 0);
	}
	return n;
}

int Socket::enviar(std::string data) {
	int n = send(sockfd, data.c_str(), data.size(), 0);
	if(n == -1)
		return -1;
	while((unsigned int)n < data.size()) {
		std::string saux = data.substr(n);
		n += send(sockfd, saux.c_str(), n - data.size(), 0);
	}
	return n;
}

void Socket::cerrar() {
	shutdown(sockfd, 2);
	close(sockfd);
}

int Socket::aceptar() {
	unsigned int clilen;
	struct sockaddr_in cli_addr;
	clilen = (socklen_t)sizeof(cli_addr);
	int clifd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
	return clifd;
}

int Socket::getFd() {
	return sockfd;
}

int Socket::getPuerto() {
	return puerto;
}
